import * as THREE from 'three';
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js';
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
import { ModelRegistry } from './ModelRegistry.js';
import { IndexedDBManager } from './IndexedDBManager.js';

export class ResourceLoader {
    constructor() {
        this.resources = new Map();
        this.loadedModels = new Map();
        this.loadingPromises = new Map();
        this.loadingProgress = new Map();
        
        // 初始化管理器
        this.modelRegistry = new ModelRegistry();
        this.dbManager = new IndexedDBManager();
        
        // 初始化加载器
        this.textureLoader = new THREE.TextureLoader();
        this.gltfLoader = new GLTFLoader();
        this.dracoLoader = new DRACOLoader();
        this.cubeTextureLoader = new THREE.CubeTextureLoader();
        
        // 设置Draco解码器
        this.dracoLoader.setDecoderPath('https://www.gstatic.com/draco/v1/decoders/');
        this.gltfLoader.setDRACOLoader(this.dracoLoader);
        
        // 设置加载管理器
        this.loadingManager = new THREE.LoadingManager();
        this.setupLoadingManager();
        
        // 进度回调
        this.onProgress = null;
        this.onComplete = null;
        this.onError = null;
        this.onModelProgress = null;
        
        // 统计信息
        this.stats = {
            totalModels: 0,
            loadedFromCache: 0,
            loadedFromNetwork: 0,
            totalSize: 0,
            startTime: 0,
            endTime: 0,
            errors: []
        };
        
        // 初始化IndexedDB
        this.initDB();
    }
    
    async initDB() {
        try {
            await this.dbManager.init();
            console.log('ResourceLoader: IndexedDB已初始化');
        } catch (error) {
            console.warn('ResourceLoader: IndexedDB初始化失败，将跳过缓存功能', error);
        }
    }
    
    setupLoadingManager() {
        this.loadingManager.onLoad = () => {
            console.log('ResourceLoader: 所有资源加载完成');
            if (this.onComplete) {
                this.onComplete();
            }
        };
        
        this.loadingManager.onProgress = (url, loaded, total) => {
            const progress = (loaded / total) * 100;
            console.log(`ResourceLoader: 加载进度 ${progress.toFixed(1)}% (${url})`);
            
            if (this.onProgress) {
                this.onProgress({
                    url,
                    loaded,
                    total,
                    progress: progress / 100
                });
            }
        };
        
        this.loadingManager.onError = (url) => {
            console.error(`ResourceLoader: 资源加载失败 ${url}`);
            this.stats.errors.push({ url, timestamp: Date.now() });
            
            if (this.onError) {
                this.onError(url);
            }
        };
        
        // 为加载器设置管理器
        this.textureLoader.manager = this.loadingManager;
        this.cubeTextureLoader.manager = this.loadingManager;
        // GLTF加载器使用自定义进度处理
    }
    
    /**
     * 预加载所有场景的模型
     * @returns {Promise<void>}
     */
    async preloadAllModels() {
        console.log('开始预加载所有模型...');
        
        this.stats.startTime = Date.now();
        const allModels = this.modelRegistry.getAllModels();
        this.stats.totalModels = allModels.length;
        
        if (allModels.length === 0) {
            console.log('没有需要预加载的模型');
            return;
        }
        
        // 显示总体进度
        if (this.onProgress) {
            this.onProgress({
                stage: 'preparing',
                total: allModels.length,
                loaded: 0,
                progress: 0,
                message: '准备加载模型...'
            });
        }
        
        // 并行加载所有模型
        const loadPromises = allModels.map((model, index) => 
            this.preloadModel(model, index)
        );
        
        try {
            await Promise.allSettled(loadPromises);
            this.stats.endTime = Date.now();
            
            const loadTime = (this.stats.endTime - this.stats.startTime) / 1000;
            console.log(`模型预加载完成！用时: ${loadTime.toFixed(2)}s`);
            console.log(`从缓存加载: ${this.stats.loadedFromCache}, 从网络加载: ${this.stats.loadedFromNetwork}`);
            
            if (this.onComplete) {
                this.onComplete({
                    stats: this.stats,
                    loadTime,
                    success: true
                });
            }
            
        } catch (error) {
            console.error('模型预加载过程中出现错误:', error);
            if (this.onError) {
                this.onError(error);
            }
        }
    }
    
    /**
     * 预加载单个模型
     * @param {Object} modelConfig - 模型配置
     * @param {number} index - 模型索引
     * @returns {Promise<void>}
     */
    async preloadModel(modelConfig, index) {
        const { id, url, name, sceneId } = modelConfig;
        
        try {
            // 检查是否已经加载过
            if (this.loadedModels.has(id)) {
                console.log(`模型 ${name} 已在内存中`);
                return;
            }
            
            // 检查缓存
            const cachedModel = await this.dbManager.getModel(id);
            
            let modelData;
            if (cachedModel) {
                // 从缓存加载
                console.log(`从缓存加载模型: ${name}`);
                modelData = await this.loadModelFromCache(cachedModel);
                this.stats.loadedFromCache++;
            } else {
                // 从网络加载
                console.log(`从网络加载模型: ${name}`);
                modelData = await this.loadModelFromNetwork(modelConfig, index);
                this.stats.loadedFromNetwork++;
            }
            
            if (modelData) {
                // 存储到内存
                this.loadedModels.set(id, {
                    ...modelConfig,
                    data: modelData,
                    loadedAt: Date.now()
                });
                
                console.log(`模型 ${name} 加载完成`);
            }
            
        } catch (error) {
            console.error(`加载模型 ${name} 失败:`, error);
            this.stats.errors.push({
                modelId: id,
                modelName: name,
                error: error.message,
                timestamp: Date.now()
            });
        }
    }
    
    /**
     * 从缓存加载模型
     * @param {Object} cachedModel - 缓存的模型数据
     * @returns {Promise<Object>} GLTF数据
     */
    async loadModelFromCache(cachedModel) {
        try {
            // 创建Blob URL用于GLTF加载器
            const blob = new Blob([cachedModel.data], { type: 'model/gltf-binary' });
            const blobUrl = URL.createObjectURL(blob);
            
            const gltf = await new Promise((resolve, reject) => {
                this.gltfLoader.load(
                    blobUrl,
                    (gltf) => {
                        URL.revokeObjectURL(blobUrl); // 清理blob URL
                        resolve(gltf);
                    },
                    undefined,
                    (error) => {
                        URL.revokeObjectURL(blobUrl);
                        reject(error);
                    }
                );
            });
            
            return gltf;
            
        } catch (error) {
            console.error('从缓存加载模型失败:', error);
            throw error;
        }
    }
    
    /**
     * 从网络加载模型
     * @param {Object} modelConfig - 模型配置
     * @param {number} index - 模型索引
     * @returns {Promise<Object>} GLTF数据
     */
    async loadModelFromNetwork(modelConfig, index) {
        const { id, url, name } = modelConfig;
        
        try {
            // 首先下载模型数据
            const response = await fetch(url);
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            
            const arrayBuffer = await response.arrayBuffer();
            this.stats.totalSize += arrayBuffer.byteLength;
            
            // 缓存到IndexedDB
            try {
                await this.dbManager.cacheModel(id, url, arrayBuffer, {
                    name,
                    size: arrayBuffer.byteLength,
                    contentType: response.headers.get('content-type')
                });
            } catch (cacheError) {
                console.warn(`缓存模型 ${name} 失败:`, cacheError);
            }
            
            // 使用ArrayBuffer创建GLTF
            const blob = new Blob([arrayBuffer], { type: 'model/gltf-binary' });
            const blobUrl = URL.createObjectURL(blob);
            
            const gltf = await new Promise((resolve, reject) => {
                this.gltfLoader.load(
                    blobUrl,
                    (gltf) => {
                        URL.revokeObjectURL(blobUrl);
                        resolve(gltf);
                        
                        // 报告单个模型加载进度
                        if (this.onModelProgress) {
                            this.onModelProgress({
                                modelId: id,
                                modelName: name,
                                index: index,
                                total: this.stats.totalModels,
                                progress: (index + 1) / this.stats.totalModels,
                                fromCache: false
                            });
                        }
                    },
                    (progress) => {
                        // 单个模型的加载进度
                        if (this.onModelProgress) {
                            this.onModelProgress({
                                modelId: id,
                                modelName: name,
                                index: index,
                                total: this.stats.totalModels,
                                progress: (index + (progress.loaded / progress.total)) / this.stats.totalModels,
                                fromCache: false,
                                loadProgress: progress
                            });
                        }
                    },
                    (error) => {
                        URL.revokeObjectURL(blobUrl);
                        reject(error);
                    }
                );
            });
            
            return gltf;
            
        } catch (error) {
            console.error(`从网络加载模型 ${name} 失败:`, error);
            throw error;
        }
    }
    
    /**
     * 获取预加载的模型
     * @param {string} modelId - 模型ID
     * @returns {Object|null} 模型数据
     */
    getPreloadedModel(modelId) {
        const model = this.loadedModels.get(modelId);
        if (model) {
            console.log(`获取预加载模型: ${model.name}`);
            return model.data;
        }
        
        console.warn(`模型 ${modelId} 未找到或未预加载`);
        return null;
    }
    
    /**
     * 检查模型是否已预加载
     * @param {string} modelId - 模型ID
     * @returns {boolean}
     */
    isModelPreloaded(modelId) {
        return this.loadedModels.has(modelId);
    }
    
    /**
     * 获取场景的所有预加载模型
     * @param {string} sceneId - 场景ID
     * @returns {Array} 模型数据数组
     */
    getSceneModels(sceneId) {
        const sceneModels = [];
        
        for (const [modelId, modelData] of this.loadedModels) {
            if (modelData.sceneId === sceneId) {
                sceneModels.push({
                    id: modelId,
                    config: modelData,
                    data: modelData.data
                });
            }
        }
        
        return sceneModels;
    }
    
    // 保留原有的纹理生成功能
    async loadResources(resourceConfigs) {
        const promises = resourceConfigs.map(config => this.loadResource(config));
        await Promise.all(promises);
        console.log(`资源加载完成，共加载 ${resourceConfigs.length} 个资源`);
    }
    
    async loadResource(config) {
        return new Promise((resolve, reject) => {
            const { name, type, url } = config;
            
            // 如果已经加载过，直接返回
            if (this.resources.has(name)) {
                resolve(this.resources.get(name));
                return;
            }
            
            // 处理程序生成的资源
            if (!url) {
                const resource = this.generateResource(type, config);
                if (resource) {
                    this.resources.set(name, resource);
                    resolve(resource);
                    return;
                }
            }
            
            // 从URL加载资源
            let loader;
            switch (type) {
                case 'texture':
                    loader = this.textureLoader;
                    break;
                case 'cubeTexture':
                    loader = this.cubeTextureLoader;
                    break;
                default:
                    reject(new Error(`不支持的资源类型: ${type}`));
                    return;
            }
            
            loader.load(
                url,
                (resource) => {
                    // 优化纹理设置
                    if (resource instanceof THREE.Texture) {
                        this.optimizeTexture(resource);
                    }
                    
                    this.resources.set(name, resource);
                    resolve(resource);
                },
                (progress) => {
                    // 进度回调
                },
                (error) => {
                    reject(error);
                }
            );
        });
    }
    
    generateResource(type, config) {
        switch (type) {
            case 'texture':
                return this.generateTexture(config);
            default:
                return null;
        }
    }
    
    generateTexture(config) {
        // 创建程序生成的纹理
        const canvas = document.createElement('canvas');
        const size = config.size || 512;
        canvas.width = size;
        canvas.height = size;
        
        const ctx = canvas.getContext('2d');
        
        // 根据配置名称生成不同的纹理
        if (config.name === 'geometryTexture') {
            this.generateGeometryTexture(ctx, size);
        } else if (config.name === 'particleTexture') {
            this.generateParticleTexture(ctx, size);
        } else {
            this.generateDefaultTexture(ctx, size);
        }
        
        const texture = new THREE.CanvasTexture(canvas);
        this.optimizeTexture(texture);
        
        return texture;
    }
    
    generateGeometryTexture(ctx, size) {
        // 创建几何图案纹理
        const gradient = ctx.createLinearGradient(0, 0, size, size);
        gradient.addColorStop(0, '#667eea');
        gradient.addColorStop(1, '#764ba2');
        
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, size, size);
        
        // 添加网格图案
        ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
        ctx.lineWidth = 2;
        
        const gridSize = size / 16;
        for (let i = 0; i <= 16; i++) {
            ctx.beginPath();
            ctx.moveTo(i * gridSize, 0);
            ctx.lineTo(i * gridSize, size);
            ctx.stroke();
            
            ctx.beginPath();
            ctx.moveTo(0, i * gridSize);
            ctx.lineTo(size, i * gridSize);
            ctx.stroke();
        }
    }
    
    generateParticleTexture(ctx, size) {
        // 创建粒子纹理（圆形渐变）
        const centerX = size / 2;
        const centerY = size / 2;
        const radius = size / 2;
        
        const gradient = ctx.createRadialGradient(
            centerX, centerY, 0,
            centerX, centerY, radius
        );
        
        gradient.addColorStop(0, 'rgba(255, 255, 255, 1)');
        gradient.addColorStop(0.3, 'rgba(255, 255, 255, 0.8)');
        gradient.addColorStop(1, 'rgba(255, 255, 255, 0)');
        
        ctx.fillStyle = gradient;
        ctx.fillRect(0, 0, size, size);
    }
    
    generateDefaultTexture(ctx, size) {
        // 默认纹理
        ctx.fillStyle = '#333333';
        ctx.fillRect(0, 0, size, size);
        
        ctx.fillStyle = '#666666';
        for (let i = 0; i < size; i += 32) {
            for (let j = 0; j < size; j += 32) {
                if ((i + j) % 64 === 0) {
                    ctx.fillRect(i, j, 32, 32);
                }
            }
        }
    }
    
    optimizeTexture(texture) {
        // 优化纹理设置以提高性能
        texture.generateMipmaps = true;
        texture.minFilter = THREE.LinearMipmapLinearFilter;
        texture.magFilter = THREE.LinearFilter;
        texture.wrapS = THREE.RepeatWrapping;
        texture.wrapT = THREE.RepeatWrapping;
        
        // 启用各向异性过滤（如果支持）
        const maxAnisotropy = 4; // 限制各向异性级别以平衡性能
        texture.anisotropy = Math.min(maxAnisotropy, texture.anisotropy);
    }
    
    getResource(name) {
        return this.resources.get(name);
    }
    
    hasResource(name) {
        return this.resources.has(name);
    }
    
    /**
     * 获取加载统计信息
     * @returns {Object} 统计信息
     */
    getStatistics() {
        return {
            ...this.stats,
            memoryModels: this.loadedModels.size,
            memoryResources: this.resources.size
        };
    }
    
    /**
     * 清理资源
     */
    dispose() {
        // 清理传统资源
        this.resources.forEach((resource, name) => {
            if (resource.dispose) {
                resource.dispose();
            }
        });
        this.resources.clear();
        
        // 清理预加载的模型
        this.loadedModels.clear();
        
        // 清理加载器
        if (this.dracoLoader) {
            this.dracoLoader.dispose();
        }
        
        // 关闭数据库连接
        if (this.dbManager) {
            this.dbManager.close();
        }
        
        console.log('ResourceLoader 资源已清理');
    }
}